package com.firebird.app.kotlin.stock.trend.service

import android.app.Service
import android.content.Intent
import android.os.*
import com.firebird.app.kotlin.stock.trend.service.UIListener
import com.firebird.app.kotlin.stock.trend.bean.Stock
import com.firebird.app.kotlin.stock.trend.net.StockDataSource
import com.firebird.app.kotlin.stock.trend.utils.Constant
import com.firebird.app.kotlin.stock.trend.utils.Log
import java.lang.ref.WeakReference
import java.util.*

/**
 * 后台服务组件，用于处理远程获取股票数据等耗时操作
 * @author ljk
 * @date   2019年12月24日
 */
class StockService : Service() {
    private var stockDataSource: StockDataSource? = null
    private var serviceThread: ServiceThread? = null
    private val serviceHandler: Handler = ServiceHandler(this) //UI线程中的handler，不能用来更新UI
    override fun onBind(intent: Intent): IBinder? {
        return null
    }
    override fun onCreate() {
        super.onCreate()
        //启动Socket通信线程
        stockDataSource = StockDataSource("192.168.0.102", 8888)
        //将UI线程中的handler出入
        stockDataSource!!.setServiceHandler(serviceHandler)
        stockDataSource!!.start()
        //启动后台服务器线程
        serviceThread = ServiceThread()
        serviceThread!!.start()
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()
        serviceThread!!.close()
        stockDataSource!!.close()
        uiListenerMap.clear()
    }

    /**
     * UI线程中的handler
     * @author ljk
     * @date   2019年4月19日
     */
    internal class ServiceHandler(stockService: StockService) : Handler() {
        private var weakReference: WeakReference<StockService>?=null
        override fun handleMessage(msg: Message) { //StockService service = weakReference.get();
//获取股票涨跌排序数据
            if (msg.what == Constant.SERVICE_QUOTATION_RANK_REQUEST) {
                Log.d(tag, "UI线程中的Handler执行,更新UI线程 flag：" + msg.arg1)
                var listener = uiListenerMap[msg.arg1]
                listener!!.refresh(msg.obj)
                //清除UIListener引用防止内存溢出
                uiListenerMap.remove(msg.what)
                listener = null
            }
        }

        init {
            weakReference = WeakReference(stockService)
        }
    }
    ///////////////////////// 非UI线程中的操作   /////////////////////////
    /**
     * 后台服务中的looper循环线程（非UI线程），可用于处理耗时操作
     * @author ljk
     * @date   2019年12月25日
     */
    internal inner class ServiceThread : Thread() {
        private var looper: Looper? = null
        fun close() {
            if (looper != null) looper!!.quit()
        }

        override fun run() {
            looper = Looper.myLooper()
            //使用looper建立消息循环的步骤
//1、初始化looper
            Looper.prepare()
            //2.绑定handler到自定义线程中，并添加处理消息的方法；
//那个线程要用来处理消息，就要把handler创建在改线程中
            serviceThreadHandler = ServiceThreadHandler(this@StockService)
            //3.启动looper循环
            Looper.loop()
            Log.i(tag, "后台服务Lopper线程启动成功！")
        }
    }

    /**
     * 自定义后台多线程中的handler
     * @author ljk
     * @date   2019年12月25日
     */
    internal class ServiceThreadHandler(stockService: StockService) : Handler() {
        private var weakReference: WeakReference<StockService>?=null
        override fun handleMessage(msg: Message) { //在该方法中进行各种耗时的后台操作
            Log.d(tag, "耗时操作：" + msg.what + " 开始进行...")
            val service = weakReference!!.get()
            //获取股票涨跌排序数据
            if (msg.what == Constant.SERVICE_QUOTATION_RANK_REQUEST) { //NIO写操作，向远处服务器发送数据
//System.out.println("NIO写操作，向远处服务器发送数据");
                service!!.stockDataSource!!.getStockRank(msg.data)
            }
        }

        init {
            weakReference = WeakReference(stockService)
        }
    }

    companion object {
        private const val tag = "StockService"
        private val uiListenerMap: MutableMap<Int, UIListener> = HashMap()
        private var serviceThreadHandler //自定义线程（非UI线程）中的handler，不能用来更新UI
                : Handler? = null
        /**
         * 获取股票行情的排序数据
         * @param start        数据起始ID
         * @param wantnum    想要获取的记录数
         * @param colunm    排序字段
         * @param desc        0.升序 1.降序
         * @param flag        异步请求中唯一标识某次请求的数字，发送时请求时传入，数据返回时原样传回
         * @param listener    异步数据请求完成后的回调接口
         */
        fun getQuotationRank(start: Int, wantnum: Int, colunm: Int, desc: Int, flag: Int, listener: UIListener) {
            val msg = Message.obtain()
            msg.what = Constant.SERVICE_QUOTATION_RANK_REQUEST
            val bundle = Bundle()
            bundle.putInt("start", start)
            bundle.putInt("wantnum", wantnum)
            bundle.putInt("colunm", colunm)
            bundle.putInt("desc", desc)
            bundle.putInt("flag", flag)
            msg.data = bundle
            uiListenerMap[flag] = listener
            serviceThreadHandler!!.sendMessage(msg)
        }
    }
}